import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

class CommonTextField extends StatefulWidget {
  final Widget? prefixIcon;
  final Widget? suffixIcon;
  final bool isPassword;
  final String? labelText;
  final String? hintText;
  final TextAlign textAlign;

  /// 内容显示在垂直方向的位置，默认是对齐top
  final TextAlignVertical? textAlignVertical;
  final TextInputType? keyboardType;
  final double? fontSize;
  final double? hintFontSize;
  final List<TextInputFormatter>? formatters;
  final EdgeInsetsGeometry? contentPadding;
  final TextEditingController? controller;
  final InputBorder? border;
  final int? maxLength;
  final int? maxLines;
  final Color? hintTextColor;
  final Color? textColor;

  /// 长度提示文本，不传入表示不显示
  final String? counterText;
  final ValueChanged<String>? valueChanged;

  const CommonTextField({
    Key? key,
    this.prefixIcon,
    this.suffixIcon,
    this.isPassword = false,
    this.controller,
    this.labelText,
    this.hintText,
    this.keyboardType,
    this.formatters,
    this.contentPadding = const EdgeInsets.fromLTRB(12, 12, 12, 12),
    this.textAlign = TextAlign.start,
    this.textAlignVertical = TextAlignVertical.top,
    this.border,
    this.fontSize,
    this.hintFontSize,
    this.maxLength,
    this.maxLines = 1,
    this.hintTextColor,
    this.textColor,
    this.counterText,
    this.valueChanged,
  }) : super(key: key);

  @override
  State<CommonTextField> createState() => _CommonTextFieldState();
}

class _CommonTextFieldState extends State<CommonTextField> {
  bool _isShow = false;
  final FocusNode _focusNode = FocusNode();

  @override
  Widget build(BuildContext context) {
    Widget? suffixIcon;
    if (widget.suffixIcon != null) {
      /// 有自定義圖標，是密碼，  帶點擊
      suffixIcon = widget.isPassword
          ? GestureDetector(
        child: widget.suffixIcon,
        onTap: () => _changeState(context),
      )

      /// 有自定義圖標，不是密碼， 不帶點擊
          : widget.suffixIcon;
    } else {
      /// 沒自定義圖標，是密碼，顯示默認圖標
      /// 沒自定義圖標，不是密碼，不展示
      if (widget.isPassword) {
        suffixIcon = GestureDetector(
          child: Padding(
            padding: const EdgeInsets.all(16),
            child: Icon(
              _isShow ? Icons.visibility : Icons.visibility_off,
              color: Theme.of(context).primaryColor,
              size: 50,
            ),
          ),
          onTap: () => _changeState(context),
        );
      }
    }
    return TextField(
      controller: widget.controller,
      obscureText: widget.isPassword ? !_isShow : false,
      focusNode: _focusNode,
      keyboardType: widget.keyboardType,
      inputFormatters: widget.formatters,
      textAlign: widget.textAlign,
      maxLength: widget.maxLength,
      maxLines: widget.maxLines,
      textAlignVertical: widget.textAlignVertical,
      onChanged: widget.valueChanged,
      style: TextStyle(fontSize: widget.fontSize, color: widget.textColor),
      decoration: InputDecoration(
          hintText: widget.hintText,
          hintStyle: TextStyle(
              fontSize: widget.hintFontSize, color: widget.hintTextColor),
          labelText: widget.labelText,

          /// 必须使用icon,使用prefix会存在一些对齐问题
          prefixIcon: widget.prefixIcon,
          suffixIcon: suffixIcon,

          /// 默认的约束是48 48，强制设置最小约束
          prefixIconConstraints: const BoxConstraints(
            minWidth: 0,
            minHeight: 0,
          ),
          suffixIconConstraints: const BoxConstraints(
            minWidth: 0,
            minHeight: 0,
          ),
          isDense: true,
          isCollapsed: true,
          contentPadding: widget.contentPadding,
          enabledBorder: widget.border,
          focusedBorder: widget.border,
          border: widget.border,
          counterText: widget.counterText ?? ""),
    );
  }

  _changeState(BuildContext context) {
    setState(() {
      _isShow = !_isShow;
    });

    /// 如果本身就在聚集中，则不用处理。
    if (_focusNode.hasFocus) {
      return;
    }

    /// 如果本来是没有焦点的，就不要聚集了。
    _focusNode.unfocus();
    _focusNode.canRequestFocus = false;
    Future.delayed(const Duration(milliseconds: 500), () {
      _focusNode.canRequestFocus = true;
    });
  }
}